package com.gonsin.gview.common.services.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONObject;
import com.gonsin.base.GPageRequest;
import com.gonsin.base.GPageResult;
import com.gonsin.base.exceptions.MyException;
import com.gonsin.gview.annotations.actions.GAction;
import com.gonsin.gview.annotations.actions.GSession;
import com.gonsin.gview.annotations.data.GDataSource;
import com.gonsin.gview.common.bean.EdificeBean;
import com.gonsin.gview.common.mapper.EdificeMapper;
import com.gonsin.gview.common.po.EdificePo;
import com.gonsin.gview.common.po.EdificeSearchPo;
import com.gonsin.gview.common.services.IEdificeService;
import com.gonsin.gview.common.utils.PageableUtils;
import com.gonsin.gview.common.utils.SessionKeys;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("gviewEdificeService")
public class EdificeServiceImpl implements IEdificeService {

    @Autowired private EdificeMapper edificeMapper;

    @Override
    public GPageResult<EdificeBean> searchEdifices(EdificeSearchPo searchPo, GPageRequest pageRequest) {
        List<EdificeBean> beans = edificeMapper.searchEdifices(searchPo, PageableUtils.toPageableMyBatis(pageRequest));
        int count = edificeMapper.countEdifices(searchPo);
        return GPageResult.result(beans, count, pageRequest);
    }

    @Override
    @GDataSource("getEdifice")
    public EdificeBean findByKey(@GSession(SessionKeys.EDIFICE_KEY) String edificeKey) {
        EdificeBean edificeBean = edificeMapper.selectById(edificeKey);
        return edificeBean;
    }

    @Override
    @GAction("updateEdifice")
    public EdificeBean updateEdifice(@GSession(SessionKeys.EDIFICE_KEY) String edificeKey, EdificePo edificePo) {
        EdificeBean edifice = edificeMapper.selectById(edificeKey);
        BeanUtil.copyProperties(edificePo, edifice, CopyOptions.create().setIgnoreNullValue(true).setIgnoreCase(true));
        edificeMapper.updateById(edifice);
        return edifice;
    }

    @SneakyThrows
    @Override
    public <T> T getModuleSetting(String edificeKey, Class<T> clazz) {
        String json = edificeMapper.getModuleSetting(edificeKey);
        if(StringUtils.isEmpty(json)){
            return clazz.newInstance();
        }
        JSONObject obj = new JSONObject(json);
        String key = clazz.getSimpleName();
        if(!obj.containsKey(key)){
            return clazz.newInstance();
        }
        return obj.get(clazz.getSimpleName(), clazz);
    }

    @Override
    @Transactional
    public <T> T saveModuleSetting(String edificeKey, Object obj) {
        Map<String, Object> map = null;
        String json = edificeMapper.getModuleSetting(edificeKey);
        if(StringUtils.isEmpty(json)){
            map = new HashMap<>();
        } else {
            map = new Gson().fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());
        }
        map.put(obj.getClass().getSimpleName(), obj);
        json = new Gson().toJson(map);
        edificeMapper.updateModuleSetting(edificeKey, json);
        return (T) obj;
    }
}
